local L = AceLibrary("AceLocale-2.2"):new("GlowFoSho")
GlowFoSho = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0","AceEvent-2.0","AceHook-2.1")
local dewdrop = AceLibrary("Dewdrop-2.0")
local currWeaponLink, currWeaponEnchant
GlowFoSho.eList = {}
local tbl = GlowFoSho.eList
local showGlowless = false
local onlyCompatible = true
--the button
local gfsbutton

--make enchant table local
local enchants = GlowFoSho_enchants

--[[

Local helper functions

--]]

--returns information about the enchant when provided with enchantID
local function GetFormulaID(enchantID)
	if tonumber(enchantID) then
		for formulaID, enchant in pairs(enchants) do
			if enchant.enchantID == enchantID then
				return formulaID
			end
		end
		return
	end
end

--creates a link for an enchanting recipe with formulaID and name
local function GetRecipeLink(formulaID)
	return "|cffffd000|Henchant:" .. formulaID .. "|h[" .. GetSpellInfo(formulaID) .. "]|h|r"
end

--sets enchant for item link to enchantID
local function SetEnchant(link, enchantID)
	local link1, link2 = string.match(link,"(.*item:%d+:)%d+(.*)")
	if link1 and link2 then
		return link1 .. enchantID .. link2
	end

	return
end

--returns the enchantID in the link
local function GetEnchant(link)
	return string.match(link,"item:%d+:(%d+)")
end

--returns the list of enchants for dewdrop menu
local function UpdateEnchantList()
	--if there is no weapon equipped, empty the list
	if not currWeaponLink then
		for k in pairs(tbl) do
			tbl[k] = nil
		end
		return
	end

	local weapMinlvl, _, _, _, is2H = select(5,GetItemInfo(currWeaponLink))
	local name
	is2H = (is2H == "INVTYPE_2HWEAPON")
	for formulaID, enchant in pairs(enchants) do
		--get rid of glowless if those should not be shown
		if enchant.glowless and not showGlowless then
			tbl[formulaID] = nil
		--remove incompatible enchants if those should not be shown
		elseif onlyCompatible and ((enchant.lvl and weapMinlvl < enchant.lvl) or (not is2H and enchant.is2H)) then
			tbl[formulaID] = nil
		else
			if enchant.is2H then
				name = enchant.name .. " (2H)"
			else
				name = enchant.name
			end
			tbl[formulaID] = L[name]
		end
	end
end

--[[

Main Addon Functions

--]]

function GlowFoSho:OnInitialize()
	--register chat commands
	self:RegisterChatCommand({"/glowfosho",L["/gfs"]},{
		name = "\232\175\149\232\161\163\233\151\180\233\153\132\233\173\148",
		desc = "\229\133\129\232\174\184\230\130\168\229\156\168\232\175\149\232\161\163\233\151\180\233\162\132\232\167\136\230\173\166\229\153\168\233\153\132\233\173\148\230\149\136\230\158\156\227\128\130",
		type = "group",
		args = {
			standby = {
				type = "toggle",
				name = L["standby"],
				desc = L["Enable/disable the addon"],
				get = function() return gfsbutton:IsShown() end,
				set = function(v) if v then self:OnEnable() else self:OnDisable() end end,
				map = { [true] = "|cff00ff00" .. L["Active"] .. "|r", [false] = "|cffff0000" .. L["Suspended"] .. "|r" },
			}
		}
	})

	--set up GlowFoSho button on the dressup frame
	gfsbutton = CreateFrame("Button","GlowFoSho_Button",DressUpFrame)
	gfsbutton:SetPoint("TOPRIGHT","DressUpFrame","TOPRIGHT",-50,-80)
	--to be compatible with CloseUp, otherwise does not receive clicks
	gfsbutton:SetFrameStrata("HIGH")
	gfsbutton:Hide()
	gfsbutton:SetWidth(25)
	gfsbutton:SetHeight(25)
	gfsbutton:SetNormalTexture("Interface\\Icons\\Ability_SearingArrow")
	gfsbutton:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square","ADD")
	--set up button click scripts
	gfsbutton:RegisterForClicks("LeftButtonUp","RightButtonUp")
	gfsbutton:SetScript("OnClick",function() if dewdrop:IsOpen(GlowFoSho_Button) then dewdrop:Close() else dewdrop:Open(GlowFoSho_Button) end end)
	gfsbutton:SetScript("OnHide",function() if dewdrop:IsOpen(GlowFoSho_Button) then dewdrop:Close() end end)
end

function GlowFoSho:OnEnable()
	--show the button
	gfsbutton:Show()

	--create the dropdown menu
	dewdrop:Register(GlowFoSho_Button,
					"point","TOPLEFT",
					"relativePoint","TOPRIGHT",
					"children",{
						type = "group",
						args = {
							getWeaponLink = {
								name = L["Show Weapon Link"],
								desc = L["Displays the link of the enchanted weapon in the chat frame."],
								type = "execute",
								func = "GetWeaponLink",
								handler = self,
								order = 10
							},
							getFormulaLink = {
								name = L["Show Enchant Link"],
								desc = L["Displays the link of the enchant currently on the weapon in the chat frame."],
								type = "execute",
								func = "GetEnchantLink",
								handler = self,
								order = 20
							},
							glowless = {
								name = L["Show Glowless Enchants"],
								desc = L["Allows you to preview enchants which do not add glow to a weapon."],
								type = "toggle",
								get = function() return showGlowless end,
								set = function(v) showGlowless = v; UpdateEnchantList() end,
								order = 30
							},
							compatible = {
								name = L["Show Only Compatible Enchants"],
								desc = L["Filters out enchants that cannot be applied to the currently previewed weapon."],
								type = "toggle",
								get = function() return onlyCompatible end,
								set = function(v) onlyCompatible = v; UpdateEnchantList() end,
								order = 35
							},
							enchants = {
								name = L["Enchants"],
								desc = L["List of weapon enchants you can preview."],
								type = "text",
								get = function() return currWeaponEnchant end,
								set = "EnchantWeaponByFormulaID",
								validate = self.eList,
								handler = self,
								order = 40
							},
							clear = {
								name = L["Clear"],
								desc = L["Removes enchant from the weapon in the dressing room."],
								type = "execute",
								func = "ClearEnchant",
								handler = self,
								order = 50
							},
						}
					},
					"dontHook", true)

	--hook onto DressUp frame functions
	self:SecureHook("DressUpItemLink")
	self:HookScript(DressUpFrame,"OnShow","OnDressUpFrameShow")
	self:HookScript(DressUpFrameResetButton,"OnClick","OnDressUpFrameResetButtonClick")

	--chat handler for enchanting over chat
	self:RegisterEvent("CHAT_MSG_WHISPER","ChatHandler")
	--filter out addon messages
	self:Hook("ChatFrame_MessageEventHandler","ChatFilter",true)
end

function GlowFoSho:OnDisable()
	--hide the button
	gfsbutton:Hide()
	--unregister dewdrop
	dewdrop:Unregister(GlowFoSho_Button)
	--unhook events
	self:UnhookAll()
	--unregister events
	self:UnregisterAllEvents()
end

--hook to DressUpItemLink function
function GlowFoSho:DressUpItemLink(link)
	if link then
		local iType
		_, link, _, _, _, iType = GetItemInfo(link)

		--if previewing weapon, set the currWeaponLink link to passed link
		if iType == ENCHSLOT_WEAPON then
			currWeaponLink = link
		end
	end

	if not currWeaponLink then
		currWeaponLink = GetInventoryItemLink("player",GetInventorySlotInfo("MainHandSlot"))
		currWeaponEnchant = nil
	end

	if currWeaponLink then
		currWeaponEnchant = GetFormulaID(GetEnchant(currWeaponLink))
	end
	UpdateEnchantList()
end

--reset previous enchants when DressUp frame shows up
function GlowFoSho:OnDressUpFrameShow(...)
	currWeaponLink = nil
	currWeaponEnchant = nil
	return self.hooks[DressUpFrame]["OnShow"](...)
end

--reset previous enchants when Reset button is pressed.
--enchant is set to currently equiped weapon data
function GlowFoSho:OnDressUpFrameResetButtonClick(...)
	currWeaponLink = GetInventoryItemLink("player",GetInventorySlotInfo("MainHandSlot"))
	if currWeaponLink then
		currWeaponEnchant = GetFormulaID(GetEnchant(currWeaponLink))
	end
	return self.hooks[DressUpFrameResetButton]["OnClick"](...)
end

--enchant and preview weapon
function GlowFoSho:EnchantWeaponByFormulaID(formulaID)
	if currWeaponLink and enchants[formulaID] then
		self:EnchantWeapon(enchants[formulaID].enchantID)
	end
end

--enchant and preview weapon by enchantID
function GlowFoSho:EnchantWeapon(enchantID)
	if currWeaponLink then
		local newLink = SetEnchant(currWeaponLink,enchantID)
		if newLink then
			DressUpItemLink(newLink)
		end
	end
end

--prints out link to the currently previewed weapon with a currently previewed enchant
function GlowFoSho:GetWeaponLink()
	if currWeaponLink then
		self:Print(currWeaponLink)
	end
end

--prints out link to a formula for the current enchant on the weapon
function GlowFoSho:GetEnchantLink()
	local formulaID = self:GetCurrEnchant()
	if formulaID then
		self:Print(GetRecipeLink(formulaID))
	else
		self:Print(L["There is no enchant on the weapon or enchant unknown."])
	end
end

--returns information about the enchant on currently preview weapon
function GlowFoSho:GetCurrEnchant()
	local enchant = enchants[currWeaponEnchant]
	if enchant then
		return currWeaponEnchant, enchant.name, enchant.enchantID, enchant.is2H, enchant.glowless
	end
end

--removes enchant from item link and previews it in dressing room
function GlowFoSho:ClearEnchant()
	if currWeaponLink then
		currWeaponLink = SetEnchant(currWeaponLink,0)
		DressUpItemLink(currWeaponLink)
	end
end

--chat handler for enchanting over chat
function GlowFoSho:ChatHandler(msg, author)
	if not string.match(msg,"^" .. L["!glow"]) then
		return
	end

	if msg == L["!glow"] then
		SendChatMessage(L["glow>"] .. " " .. L["Syntax: !glow <weapon link> <enchant link>"],"WHISPER",nil,author)
		return
	end

	local weaponLink = string.match(msg,"|c%x+|Hitem:.-|h|r")
	if weaponLink and select(6,GetItemInfo(weaponLink)) == ENCHSLOT_WEAPON then
		local formulaID = string.match(msg,"Henchant:(%d+)")
		if formulaID then
			enchant = enchants[formulaID]
			if enchant then
				SendChatMessage(L["glow>"] .. " ".. SetEnchant(weaponLink,enchant.enchantID),"WHISPER",nil,author)
			else
				SendChatMessage(L["glow>"] .. " " .. L["Unknown enchant."],"WHISPER",nil,author)
			end
		else
			SendChatMessage(L["glow>"] .. " " .. L["No weapon enchant link specified."],"WHISPER",nil,author)
		end
	else
		SendChatMessage(L["glow>"] .. " " .. L["No weapon link specified."],"WHISPER",nil,author)
	end
end

--prevents addon messages from displaying in the chat window
function GlowFoSho:ChatFilter(event,...)
	local msg = arg1
	--block incomming requests
	if event == "CHAT_MSG_WHISPER" and string.match(msg,"^" .. L["!glow"]) then
		return true
	end

	--block replies
	if event == "CHAT_MSG_WHISPER_INFORM" and string.match(msg,"^" .. L["glow>"]) then
		return true
	end

	return self.hooks["ChatFrame_MessageEventHandler"](event,...)
end
